import { ExecutionContext, ForbiddenException, Inject, Injectable, UnauthorizedException } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { Reflector } from "@nestjs/core";
import { UserService } from "@/modules/user/user.service";
import { ALLOW_ANON } from "@/decorators/allow-anon.decorator";

@Injectable()
export class JwtAuthGuard extends AuthGuard("jwt") {
    constructor(
        private readonly reflector: Reflector,
        @Inject(UserService)
        private readonly userService: UserService
    ) {
        super();
    }
    
    async canActivate(ctx: ExecutionContext): Promise<boolean> {
        // 函数，类 是否允许 无 token 访问
        const allowAnon = this.reflector.getAllAndOverride<boolean>(ALLOW_ANON, [ctx.getHandler(), ctx.getClass()]);
        if (allowAnon) return true;
        const req = ctx.switchToHttp().getRequest();
        // const res = ctx.switchToHttp().getResponse()
        const accessToken = req.get("Authorization");
        // console.log("accessToken",accessToken)
        if (!accessToken) throw new ForbiddenException("请先登录");
        const atUserId = this.userService.verifyToken(accessToken); // 自定义 token 校验
        // console.log("atUserId",atUserId)
        if (!atUserId) throw new UnauthorizedException("当前登录已过期，请重新登录");
        return this.activate(ctx);
    }
    
    async activate(ctx: ExecutionContext): Promise<boolean> {
        return super.canActivate(ctx) as Promise<boolean>;
    }
}
